
#include "video/SubMeshRenderGroup.h"
#include "video/Texture.h"
#include "video/Material.h"
#include "video/Device.h"
#include "defines.h"

namespace KEngine
{


SubMeshRenderGroup::SubMeshRenderGroup(Device* device)
: mMaterial(NULL)
, mIndexBuffer(NULL)
,mDevice(device)
{

}

SubMeshRenderGroup::~SubMeshRenderGroup()
{
	KSafeRelease(mIndexBuffer);
}

void SubMeshRenderGroup::setMtl(Material* mtl)
{
	mMaterial = mtl;
}

Material* SubMeshRenderGroup::getMtl() const
{
	return mMaterial;
}

void SubMeshRenderGroup::addVertexIndex(DWORD idx)
{
	mVIList.push_back(idx);
}

void SubMeshRenderGroup::optimize()
{
	if (mVIList.empty())
		return;

	int numIndex = mVIList.size();
	mIndices.assign(numIndex);
	for (int i = 0; i < numIndex; ++i)
		mIndices[i] = mVIList[i];
	mVIList.clear();

	// update d3d index buffer
	updateIndexBuffer();
}

void SubMeshRenderGroup::render(int numVertex)
{
	ID3DDevice* d3dDevice = mDevice->getDevice();

	// set d3d index buffer
	d3dDevice->SetIndices(mIndexBuffer);
	d3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0, numVertex, 0, mIndices.size() / 3);
	d3dDevice->SetTexture(0, NULL);
}

void SubMeshRenderGroup::updateIndexBuffer(bool forceCreate /* = false */)
{
	unsigned int buffSize = mIndices.size() * sizeof(DWORD);

	if (mIndexBuffer == NULL || forceCreate)
		mDevice->getDevice()->CreateIndexBuffer(buffSize, D3DUSAGE_WRITEONLY, D3DFMT_INDEX32, D3DPOOL_MANAGED, &mIndexBuffer, NULL);

	void* buff = NULL;
	mIndexBuffer->Lock(0, buffSize, &buff, 0);
	memcpy(buff, mIndices.base(), buffSize);
	mIndexBuffer->Unlock();
}

}